home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Cream of the Crop 1
/
Cream of the Crop 1.iso
/
PROGRAM
/
PCW_C.ARJ
/
PCTSCRN.ASM
< prev
next >
Wrap
Assembly Source File
|
1991-12-16
|
30KB
|
591 lines
Title Tscrn.Asm
Page ,120
;****************************************************************
;* File Id. Pctscrn.Asm *
;* Author. Stan Milam. *
;* Date Written. 11/03/88. *
;* Date Last Modified. 11/03/88. *
;* *
;* (c) Copyright 1989, 1990 by Stan Milam *
;* *
;* Modifications: This file was modified to work with Power C. *
;* Powerc does not prefix global symbols with the underscore (_)*
;* and to retrieve parameters off of the stack. *
;* Also, the save screen function had to be modified to make *
;* sure that ES has the same value as DS upon entry. Otherwise, *
;* you are saving the screen to something pointed to by ES:DI. *
;* *
;* Comments: This file is represents a group of Assembler *
;* routines designed to make screen handling in C more powerful.*
;* Featured routines for screen save & restore, quick screen *
;* writes with color. *
;* *
;* NOTE: This file is assembled with Micorsoft MASM 5.10, but *
;* can be assembled using Borland's Turbo C. *
;****************************************************************
;
SyncCntl Equ 200
True Equ 1
False Equ 0
MaxMove Equ 2000
Dosseg ;Use standard segmentation
.Model Huge
.Data
Extrn CheckSnow:Word
Extrn Vbump:Word
.Code
Page
;
;****************************************************************
;* Tputchar *
;* *
;* This routine will write a character to the screen with a *
;* color attribute at the specified row, col *
;* *
;* Uses: Sync_Wait *
;* Prototype: *
;* void Tputchar(int far *scrnptr, int attrchar); *
;****************************************************************
;
Public Tputchar
Tputchar Proc Far
Push Bp
Mov Bp,Sp
Push Di
Push Es
Push Ax
Mov Ax,[Bp + 10] ;Put attribut & character in Ax
Les Di,[Bp + 6] ;Get Screen pointer
Cmp [CheckSnow],True
Jne Putchar
Call Sync_Wait
Putchar:
Stosw ;Put the attr & char in video
Pop Ax
Pop Es
Pop Di
Pop Bp
Ret
Tputchar Endp
Page
;
;****************************************************************
;* Tputs *
;* *
;* This routine will be used to write character strings into *
;* video memory with color attribute. It will return the number*
;* characters written. *
;* *
;* Prototype: *
;* int Tputs(far *Sptr, char far *strptr, int attr) *
;****************************************************************
;
Public Tputs ;Make function global
Tputs Proc Far
Push Bp
Mov Bp,Sp
Push Si
Push Di
Push Es ;Save Es
Push Cx ;Save Cx
Xor Cx,Cx ;Clear Cx
Mov Ax,[Bp + 14] ;Get color attribute
Lds Si,[Bp + 10] ;Get string pointer
Les Di,[Bp + 6] ;point to screen memory ES:DI
Cmp [CheckSnow],True ;Need to wait for vertical sync?
Jne Twrite ;No - proceed
Call Sync_Wait ;Yes - so wait
Twrite: Lodsb ;Get character from string
Or Al,Al ;Is it a '\0'?
Jz Exit ;Yes - we are done
Stosw ;Else put attr & char in video
Inc Cx ;Add 1 to our count
Jmp Twrite ;And do it all again
Exit:
Mov Ax,Cx ;Return the count
Pop Cx ;Restore Cx
Pop Es ;Restore Es
Pop Di
Pop Si
Mov Sp,Bp
Pop Bp
Ret
Tputs Endp
Page
;
;****************************************************************
;* Tvputs *
;* *
;* This routine will write a string vertically on the screen. *
;* *
;* Uses: Sync_Wait *
;* C Prototype: *
;* Tvputs((int far *) ScrnSeg, (char far *) str, int attr); *
;****************************************************************
;
Public Tvputs
Tvputs Proc Far
Push Bp ;Save Bp
Mov Bp,Sp ;Set up the stack frame
Push Es ;
Push Ds ;
Push Si ;
Push Di ;
Push Ax ;
Push Bx ;
Push Dx ;
Mov Bx,[CheckSnow] ;Save CheckSnow in Bx
Mov Dx,[Vbump] ;Save vertical increment
Les Di,[Bp + 6] ;Gets Pointer to Screen Segment
Lds Si,[Bp + 10] ;Get Pointer to String
Mov Ax,[Bp + 14] ;Get Color Attribute in Ax
Cmp Bx,True ;Need to call Sync_Wait?
Jne Tvwrite ;No - proceed
Call Sync_Wait ;Wait for vertical retrace
Tvwrite: ;
Lodsb ;Get Char & Attribute in Ax
Or Al,Al ;Is Char '\0'
Jz Tvend ;Yes - We are done
Push Di ;Save current column
Stosw ;Write to Screen Memory
Pop Di ;Restore Column
Add Di,Dx ;Next Column
Jmp Tvwrite ;Go back to do it again
Tvend: ;
Pop Dx ;
Pop Bx ;
Pop Ax ;
Pop Di ;Restore Registers
Pop Si ;
Pop Ds ;
Pop Es ;
Mov Sp,Bp ;Restore Stack Frame
Pop Bp ;Restore Bp or Die!
Ret ;Return to C program
Tvputs Endp
Page
;
;****************************************************************
;* SaveScrn *
;* *
;* This module will be used to save a specified block of a *
;* screen in a character buffer. *
;* *
;* Uses Sync_Wait *
;* Prototype: *
;* int SaveScrn(int rows, int cols, int far *scrnptr, char *ptr*
;* *
;****************************************************************
Public SaveScrn
SaveScrn Proc Far
Push Bp
Mov Bp,Sp
Push Si ;
Push Di ;
Push Ds ;Save the Regs!
Push Es ;
Push Ax ;
Push Bx ;
Push Cx ;
Push Dx ;
;
Xor Dx,Dx ;Clear Dx
Mov Bx,[CheckSnow] ;Save Snow indicator
Mov Ax,[Vbump] ;Save vertical increment
Lds Si,[Bp + 10] ;get pointer to screen
Les Di,[Bp + 14] ;pointer to save buffer
Mov Cx,[Bp + 6] ;get number of rows
Cmp Bx,True ;Check for CGA monitor
Jne SaveRow ;Not a CGA so go ahead
Call Sync_Wait ;Otherwise wait for vert sync
SaveRow:
Push Cx ;Save the Number of rows to go
Push Si ;Save screen offset
Mov Cx,[Bp + 8] ;get # of cols
Cmp Bx,True ;CGA monitor?
Jne Save ;No - go ahead.
Cmp Dx,SyncCntl ;Ax > SyncCntl?
Jl Save ;Yes - Go Ahead
Xor Dx,Dx ;Else clear Ax
Call Sync_Wait ;and wait for vert sync
Save:
Add Dx,Cx ;Accumulate number of words
Rep Movsw ;Save quickly
Pop Si ;Pop screen offset
Add Si,Ax ;Bump offset to next screen row
Pop Cx ;Pop number of rows to go
Loop SaveRow ;Do again if Cx != zero
Pop Dx ;
Pop Cx ;
Pop Bx ;
Pop Ax
Pop Es ;Restore the Regs!
Pop Ds ;
Pop Di ;
Pop Si ;
Mov Sp,Bp
Pop Bp
Xor Ax,Ax ;Send back zero return code
Ret
SaveScrn Endp
Page
;
;****************************************************************
;* RestoreScrn *
;* *
;* This routine will restore a previously saved screen. *
;* *
;* Uses: Sync_Wait *
;* ProtoType: *
;* int RestoreScrn(int rows, int cols, int far *sptr, char ch *
;****************************************************************
;
Public RestoreScrn
RestoreScrn Proc Far
Push Bp
Mov Bp,Sp
Push Ds ;
Push Es ;
Push Di ;
Push Si ;Save the Regs
Push Ax ;
Push Cx ;
Push Bx ;
Push Dx
Mov Bx,[CheckSnow]
Mov Dx,[Vbump]
Xor Ax,Ax ;Clear Ax
Les Di,[Bp + 10] ;Get screen pointer
Lds Si,[Bp + 14] ;Get pointer to buffer
Mov Cx,[Bp + 6] ;Get number of Rows
Cmp Bx,1 ;Check for CGA
Jne RestoreRow
Call Sync_Wait ;Call sync_wait if CGA
RestoreRow:
Push Cx ;Save the rows to go
Push Di ;Save screen offset
Mov Cx,[Bp + 8] ;Get number of columns
Cmp Bx,1 ;Check for CGA
Jne Restore ;Go around if not
Cmp Ax,SyncCntl ;Is Ax > SyncCntl
Jl ReStore ;Yes: Go Ahead
Xor Ax,Ax ;Zero Ax
Call Sync_Wait ;And Call Sync_Wait
Restore:
Add Ax,Cx ;Add number of cols to Ax
Rep Movsw ;Restore a row on screen
Pop Di ;Pop screen offset
Add Di,Dx ;Bump offset 1 row
Pop Cx ;Pop # of rows to go
Loop RestoreRow ;Do again if Cx != 0
Pop Dx ;
Pop Bx ;
Pop Cx ;
Pop Ax ;
Pop Si ;Restore Regs!
Pop Di ;
Pop Es ;
Pop Ds ;
Mov Sp,Bp
Pop Bp
Xor Ax,Ax ;Send 0 return code back
Ret
RestoreScrn Endp
Page
;
;****************************************************************
;* TextFill *
;* *
;* This routine will define the window by filling the rectan- *
;* gular area with a color attribute and spaces. Needless to *
;* say, this is usualy done after the area has been saved away. *
;* *
;* Uses: Sync_Wait. *
;* Prototype: *
;* void TextFill(int rows, int cols, int far *sptr, int attrchr)*
;****************************************************************
;
Public TextFill
TextFill Proc Far
Push Bp ;
Mov Bp,Sp ;
Push Si ;
Push Di ;
Push Ds ;
Push Es ;Save Registers
Push Ax ;
Push Bx ;
Push Cx ;
Push Dx ;
Xor Dx,Dx ;Clear Dx
Mov Bx,[CheckSnow] ;Save in Bx
Mov Si,[Vbump] ;Save in Si
Mov Cx,[Bp + 6] ;Get # of rows
Les Di,[Bp + 10] ;Get pointer to screen
Mov Ax,[Bp + 14] ;Get color attr & space
Cmp Bx,True ;Is CGA active?
Jne Fill ;No, continue on
Call Sync_Wait ;Yes, wait for vert sync
Fill:
Push Cx ;Save number of rows to go
Push Di ;Save screen offset
Mov Cx,[Bp + 8] ;Move in number of columns
Cmp Bx,True ;CGA active?
Jne Fill1 ;No so skip
Cmp Dx,SyncCntl ;Dx < SyncCntl?
Jl Fill1 ;Yes so skip
Xor Dx,Dx ;Clear Dx
Call Sync_Wait ;Wait for vertical sync
Fill1:
Add Dx,Cx ;Add to count control
Rep Stosw ;Store attr & character in Ax
Pop Di ;Get offset back
Add Di,Si ;Bump it by 1 screen row
Pop Cx ;Get number of rows back
Loop Fill ;and repeat until finished
Pop Dx ;
Pop Cx ;
Pop Bx ;
Pop Ax ;Restore Regs!
Pop Es ;
Pop Ds ;
Pop Di ;
Pop Si ;
Mov Sp,Bp
Pop Bp
Xor Ax,Ax ;Return zero return code
Ret
TextFill Endp
Page
;
;****************************************************************
;* TvertChar *
;* *
;* This function will write a character to the screen repeatedly*
;* The number of time the character will be written is *
;* spcecified by 'count'. *
;* *
;* Prototype: *
;* void Tvertchar(int count, int charattr, int far *scrnptr); *
;****************************************************************
;
Public Tvertchar
Tvertchar Proc Far
Push Bp
Mov Bp,Sp
Push Ax ;
Push Cx ;Save Regs
Push Es ;
Push Di ;
Mov Cx,[Bp + 6] ;Get the count
Mov Ax,[Bp + 8] ;Get char & attribute
Les Di,[Bp + 10] ;Pointer to screen memory
Cmp [CheckSnow],True ;Is CheckSnow True?
Jne VertLoop ;No - go right to it
Call Sync_Wait ;Wait for Vert Sync
VertLoop:
Push Di ;Save screen offset
Stosw ;Put the character to memory
Pop Di ;Return the segment
Add Di,[Vbump] ;Bump to next row
Loop VertLoop ;Do it again
Pop Di ;
Pop Es ;
Pop Cx ;Restore Registers
Pop Ax ;
Mov Sp,Bp ;
Pop Bp ;
Ret
Tvertchar Endp
Page
;
;****************************************************************
;* Thorzchar *
;* *
;* This routine will repeatedly write a character horizontally *
;* across the screen. The number of times the character is *
;* is written is determined by the count in Cx. *
;* Prototype: *
;* void Thorzchar(int count, int chrattr, int far *scrnptr) *
;****************************************************************
;
Public Thorzchar
Thorzchar Proc Far
Push Bp ;
Mov Bp,Sp ;
Push Ax ;
Push Cx ;Save Registers
Push Di ;
Push Es ;
Mov Cx,[Bp + 6] ;Get the count
Mov Ax,[Bp + 8] ;Get character & attribute
Les Di,[Bp + 10] ;Get pointer to screen mem
Cmp [CheckSnow],True ;Is it a CGA?
Jne HorzLoop ;No!
Call Sync_Wait ;Yes - Wait for vert sync
HorzLoop:
Rep Stosw ;Continually write char
Pop Es ;Restore Registers
Pop Di ;
Pop Cx ;
Pop Ax ;
Pop Bp ;
Ret ;Return to calling C pgm
Thorzchar Endp
Page
;
;****************************************************************
;* Tchg_Attr *
;* *
;* This function will change the attributes of a specified num- *
;* ber of columns on the screen. *
;* *
;* C Prototype: *
;* Tchg_Attr(int far *scrnptr, int count, int attr); *
;****************************************************************
;
Public Tchg_Attr
Tchg_Attr Proc Far
Push Bp ;Set up stack frame
Mov Bp,Sp ;
Push Ax ;Save registers
Push Cx ;
Push Dx ;
Push Si ;
Push Di ;
Push Ds ;
Push Es ;
Mov Dx,[CheckSnow] ;Save in Dx
Lds Si,[Bp + 6] ;Get Segment/Offset to scrn
Les Di,[Bp + 6] ;Get it again
Mov Cx,[Bp + 10] ;Get number of columns
Mov Ax,[Bp + 12] ;Get Attribute (in Ah)
Cmp Dx,True ;Is it CGA?
Jne Tchg ;No!
Call Sync_Wait ;Yes - wait for vert sync
Tchg:
Lodsb ;Read character from screen
Inc Si ;Bump past screen attribute
Stosw ;Write char & attr to screen
Loop Tchg ;Do it again
Pop Es ;Restore Registers
Pop Ds ;
Pop Di ;
Pop Si ;
Pop Dx ;
Pop Cx ;
Pop Ax ;
Pop Bp ;
Ret ;Return to Calling C Pgm
Tchg_Attr Endp
Page
;*********************************************************************
;* Tscroll *
;* *
;* Low level routine to scroll the video screen up & down. *
;* *
;* Tscroll(void far *srce, void far *dest, int row, int col, int dir)*
;*********************************************************************
Source Equ [Bp + 6] ;Source pointer to video memory
Dest Equ [Bp +10] ;And the destination
Rows Equ [Bp +14] ;Number of Rows
Cols Equ [Bp +16] ;Number of Cols
Dir Equ [Bp +18] ;Direction - Up or Down
Public Tscroll
Tscroll Proc Far
Push Bp
Mov Bp,Sp ;Save Stack Frame
Push Ax ;Save All Registers Used
Push Bx
Push Cx
Push Dx
Push Di
Push Si
Push Ds
Push Es
Pushf ;Save flags - we change direction
Xor Dx,Dx ;Clear Accumulator
Mov Bx,[CheckSnow] ;Save before changing Ds
Mov Bh,Bl ;Put in Bh
Mov Ax,Dir ;Get Direction Flag
Mov Bl,Al ;Save it in Bl
Mov Ax,[Vbump] ;Save before Changing Ds
Lds Si,Source ;Get source pointer off of stack
Les Di,Dest ;Get Destination pointer
Mov Cx,Rows ;Get The number of Rows
Cld ;Set direction flag forward
Cmp Bh,1 ;Is monitor a CGA?
Jne Scroll_Line ;No
Call Sync_Wait ;Yes wait for vertical sync
Scroll_Line:
Push Si ;Save pointers
Push Di ;
Push Cx ;Save Number of Rows to go
Mov Cx,Cols ;Get number of columns to save
Cmp Bh,1 ;Do we have a CGA?
Jne Moveit ;No just save
Add Dx,Cx ;Accumulate number of bytes saved
Cmp Dx,SyncCntl ;Have we saved all we can?
Jl Moveit ;No continue onward and downward
Xor Dx,Dx ;Clear accumulator
Call Sync_Wait ;Wait for vertical retrace
Moveit: Rep Movsw ;Save a Row
Pop Cx ;Restore row count
Pop Di ;Restore Screen pointers
Pop Si
Cmp Bl,0 ;Going Down?
Jne Adjust_Up ;No
Sub Si,Ax ;Mov Pointer up
Sub Di,Ax ;
Loop Scroll_Line ;Scroll one more line
Jmp Scroll_Exit ;Exit when done
Adjust_Up:
Add Si,Ax ;Move pointers to next row
Add Di,Ax ;
Loop Scroll_Line ;Scroll one more line
Scroll_Exit: Popf ;Retore all saved registers
Pop Es ;
Pop Ds ;
Pop Si ;
Pop Di ;Restore Regs & Stack
Pop Dx ;
Pop Cx ;
Pop Bx ;
Pop Ax ;
Pop Bp ;
Ret ;Return to caller
Tscroll Endp
Page
;
;****************************************************************
;* Sync_Wait *
;* *
;* A useful procedure to wait for the vertical sync of CGA *
;* monitors. *
;****************************************************************
;
Sync_Wait Proc Near
Push Ax
Push Dx
Cli
Mov Dx,3DAh
Not_Sync:
In Al,Dx
And Al,08h
Jnz Not_Sync
Sync:
In Al,Dx
And Al,08h
Jz Sync
Pop Dx
Pop Ax
Sti
Ret
Sync_Wait Endp
End